home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / mesa / mesa-tk / src-tk.aos / image.c < prev    next >
C/C++ Source or Header  |  2000-02-23  |  5KB  |  213 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #include "awindow.h"
  6.  
  7. /* TODO: stdio to dos.library */
  8. /* TODO: malloc to AllocVecPooled */
  9.  
  10. #ifndef SEEK_SET
  11. #define SEEK_SET 0
  12. #endif
  13.  
  14. /******************************************************************************/
  15.  
  16. typedef struct _rawImageRec {
  17.   unsigned short imagic;
  18.   unsigned short type;
  19.   unsigned short dim;
  20.   unsigned short sizeX, sizeY, sizeZ;
  21.   unsigned long min, max;
  22.   unsigned long wasteBytes;
  23.   char name[80];
  24.   unsigned long colorMap;
  25.   FILE *file;
  26.   unsigned char *tmp, *tmpR, *tmpG, *tmpB;
  27.   unsigned long rleEnd;
  28.   GLuint *rowStart;
  29.   GLint *rowSize;
  30. } rawImageRec;
  31.  
  32. /******************************************************************************/
  33.  
  34. static void ConvertShort(unsigned short *array, long length)
  35. {
  36.   unsigned long b1, b2;
  37.   unsigned char *ptr;
  38.  
  39.   ptr = (unsigned char *)array;
  40.   while (length--) {
  41.     b1 = *ptr++;
  42.     b2 = *ptr++;
  43.     *array++ = (b1 << 8) | (b2);
  44.   }
  45. }
  46.  
  47. static void ConvertLong(GLuint * array, long length)
  48. {
  49.   unsigned long b1, b2, b3, b4;
  50.   unsigned char *ptr;
  51.  
  52.   ptr = (unsigned char *)array;
  53.   while (length--) {
  54.     b1 = *ptr++;
  55.     b2 = *ptr++;
  56.     b3 = *ptr++;
  57.     b4 = *ptr++;
  58.     *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
  59.   }
  60. }
  61.  
  62. static rawImageRec *RawImageOpen(char *fileName)
  63. {
  64.   union {
  65.     int testWord;
  66.     char testByte[4];
  67.   } endianTest;
  68.   rawImageRec *raw;
  69.   GLenum swapFlag;
  70.   int x;
  71.  
  72.   endianTest.testWord = 1;
  73.   if (endianTest.testByte[0] == 1)
  74.     swapFlag = GL_TRUE;
  75.   else
  76.     swapFlag = GL_FALSE;
  77.  
  78.   if (!(raw = (rawImageRec *) malloc(sizeof(rawImageRec)))) {
  79.     printf("Out of memory!\n");
  80.     tkQuit();
  81.   }
  82.   if ((raw->file = fopen(fileName, "rb")) == NULL) {
  83.     perror(fileName);
  84.     tkQuit();
  85.   }
  86.  
  87.   fread(raw, 1, 12, raw->file);
  88.  
  89.   if (swapFlag)
  90.     ConvertShort(&raw->imagic, 6);
  91.  
  92.   raw->tmp = (unsigned char *)malloc(raw->sizeX * 256);
  93.   raw->tmpR = (unsigned char *)malloc(raw->sizeX * 256);
  94.   raw->tmpG = (unsigned char *)malloc(raw->sizeX * 256);
  95.   raw->tmpB = (unsigned char *)malloc(raw->sizeX * 256);
  96.   if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
  97.       raw->tmpB == NULL) {
  98.     printf("Out of memory!\n");
  99.     tkQuit();
  100.   }
  101.  
  102.   if ((raw->type & 0xFF00) == 0x0100) {
  103.     x = raw->sizeY * raw->sizeZ * sizeof(GLuint);
  104.     raw->rowStart = (GLuint *) malloc(x);
  105.     raw->rowSize = (GLint *) malloc(x);
  106.     if (raw->rowStart == NULL || raw->rowSize == NULL) {
  107.       fprintf(stderr, "Out of memory!\n");
  108.       tkQuit();
  109.     }
  110.     raw->rleEnd = 512 + (2 * x);
  111.     fseek(raw->file, 512, SEEK_SET);
  112.     fread(raw->rowStart, 1, x, raw->file);
  113.     fread(raw->rowSize, 1, x, raw->file);
  114.     if (swapFlag) {
  115.       ConvertLong(raw->rowStart, x / sizeof(GLuint));
  116.       ConvertLong((GLuint *) raw->rowSize, x / sizeof(GLint));
  117.     }
  118.   }
  119.  
  120.   return raw;
  121. }
  122.  
  123. static void RawImageClose(rawImageRec * raw)
  124. {
  125.   fclose(raw->file);
  126.   free(raw->tmp);
  127.   free(raw->tmpR);
  128.   free(raw->tmpG);
  129.   free(raw->tmpB);
  130.   free(raw);
  131. }
  132.  
  133. static void RawImageGetRow(rawImageRec * raw, unsigned char *buf, int y, int z)
  134. {
  135.   unsigned char *iPtr, *oPtr, pixel;
  136.   int count;
  137.  
  138.   if ((raw->type & 0xFF00) == 0x0100) {
  139.     fseek(raw->file, raw->rowStart[y + z * raw->sizeY], SEEK_SET);
  140.     fread(raw->tmp, 1, (unsigned int)raw->rowSize[y + z * raw->sizeY],
  141.       raw->file);
  142.  
  143.     iPtr = raw->tmp;
  144.     oPtr = buf;
  145.     while (1) {
  146.       pixel = *iPtr++;
  147.       count = (int)(pixel & 0x7F);
  148.       if (!count) {
  149.     return;
  150.       }
  151.       if (pixel & 0x80) {
  152.     while (count--) {
  153.       *oPtr++ = *iPtr++;
  154.     }
  155.       }
  156.       else {
  157.     pixel = *iPtr++;
  158.     while (count--) {
  159.       *oPtr++ = pixel;
  160.     }
  161.       }
  162.     }
  163.   }
  164.   else {
  165.     fseek(raw->file, 512 + (y * raw->sizeX) + (z * raw->sizeX * raw->sizeY), SEEK_SET);
  166.     fread(buf, 1, raw->sizeX, raw->file);
  167.   }
  168. }
  169.  
  170. static void RawImageGetData(rawImageRec * raw, TK_RGBImageRec * final)
  171. {
  172.   unsigned char *ptr;
  173.   int i, j;
  174.  
  175.   final->data = (unsigned char *)malloc((raw->sizeX + 1) * (raw->sizeY + 1) * 4);
  176.   if (final->data == NULL) {
  177.     fprintf(stderr, "Out of memory!\n");
  178.     tkQuit();
  179.   }
  180.  
  181.   ptr = final->data;
  182.   for (i = 0; i < (int)(raw->sizeY); i++) {
  183.     RawImageGetRow(raw, raw->tmpR, i, 0);
  184.     RawImageGetRow(raw, raw->tmpG, i, 1);
  185.     RawImageGetRow(raw, raw->tmpB, i, 2);
  186.     for (j = 0; j < (int)(raw->sizeX); j++) {
  187.       *ptr++ = *(raw->tmpR + j);
  188.       *ptr++ = *(raw->tmpG + j);
  189.       *ptr++ = *(raw->tmpB + j);
  190.     }
  191.   }
  192. }
  193.  
  194. TK_RGBImageRec *tkRGBImageLoad(char *fileName)
  195. {
  196.   rawImageRec *raw;
  197.   TK_RGBImageRec *final;
  198.  
  199.   raw = RawImageOpen(fileName);
  200.   final = (TK_RGBImageRec *) malloc(sizeof(TK_RGBImageRec));
  201.   if (final == NULL) {
  202.     fprintf(stderr, "Out of memory!\n");
  203.     tkQuit();
  204.   }
  205.   final->sizeX = raw->sizeX;
  206.   final->sizeY = raw->sizeY;
  207.   RawImageGetData(raw, final);
  208.   RawImageClose(raw);
  209.   return final;
  210. }
  211.  
  212. /******************************************************************************/
  213.